import { Widget } from '@/models'
import { ApplyPage, WidgetKind } from '@/types'
import { processData } from '@/utils'

/** 批量指定页面过滤 - 输入 */
export function batchPageInputFilter(val: string) {
  return (
    val
      // 中文逗号转英文，不允许多个逗号
      .replace(/[，,]+/g, ',')

      // 限制输入的字符
      .replace(/[^\d\-,]+/g, '')

      // 去除：开头非 1-9；,-后非 1-9；,- 前非数字
      .replace(/^[^1-9]|([,-])[^1-9]|\D([,-])/g, '$1')

      // 去除：`1-5-` 中多余的 -
      .replace(/(\-\d+)\-/g, '$1')
  )
}

/** 批量指定页面过滤 - 失焦 */
export function batchPageBlurFilter(val: string) {
  // 去除首尾非数字
  return val.replace(/^(\D+)|(\D+)$/g, '')
}

/** 数字字符串列表排序 */
function sortNumberList(list: string[]) {
  return list.sort((a: string, b: string) => parseInt(a) - parseInt(b))
}

/** 批量指定页面 - 重排 */
export function batchPageArrange(val: string) {
  let list = val.split(/\s?,\s?/).map(v => {
    const pair = v.split('-')

    // `5` => `5`
    if (pair.length < 2) return v

    // `5-5` => `5`
    if (pair[0] === pair[1]) return pair[0]

    // `7-5` => `5-7`
    return sortNumberList(pair).join('-')
  })

  // 去重并排序
  list = sortNumberList(Array.from(new Set(list)))

  return list.join(',')
}

/** 批量指定页面 - 格式化，逗号追加空格 */
export function batchPageFormat(val: string) {
  return val.replace(/,(\d)/g, ', $1')
}

/** 批量指定页面 - 过滤 */
export function batchPageFilter(val: string) {
  return processData(val, batchPageInputFilter, batchPageBlurFilter, batchPageArrange, batchPageFormat)
}

/** 解析指定页 */
export function resolveBatchPage(val: string) {
  return batchPageFilter(val)
    .split(/\s?,\s?/)
    .reduce(
      (res, i) => {
        const { list, range } = res
        // 页码区间
        if (i.includes('-')) {
          range.push(
            i
              .split('-')
              .map(j => parseInt(j) - 1)
              .slice(0, 2) as [number, number]
          )
        } else {
          // 页码
          list.push(parseInt(i) - 1)
        }

        return res
      },
      {
        /** 页码列表 */
        list: [] as number[],

        /** 页码范围列表 */
        range: [] as [number, number][]
      }
    )
}

/** 获取控件所在页码列表 */
export function getWidgetPages(widget: Widget) {
  const { applyPage, p } = widget

  // 普通控件：仅当前页
  if (widget.kind === WidgetKind.NORMAL) return [p]

  // 所有页面
  const all = widget.doc?.pages.map(page => page.p) || [p]

  // 未设置：所有页
  if (!applyPage) return all

  // 奇数页
  if (applyPage === ApplyPage.ODD) return all.filter(p => (p + 1) % 2)

  // 偶数页
  if (applyPage === ApplyPage.EVEN) return all.filter(p => !((p + 1) % 2))

  // 指定页
  if (/\d/.test(applyPage)) {
    const { list, range } = resolveBatchPage(applyPage)

    return all.filter(p => isPageInApply(p, { list, range }))
  }

  return all
}

/** 页面是否在指定页 */
function isPageInApply(p: number, { list, range }: ReturnType<typeof resolveBatchPage>) {
  return list.includes(p) || range.some(([s, e]) => p >= s && p <= e)
}

/**
 * 控件是否在指定页
 * @description
 * 不使用 `widget.pages` 判断，避免超多页面文档性能问题
 */
export function isWidgetInPage(widget: Widget, p: number, docId = widget.docId) {
  if (docId !== widget.docId) return false

  const { kind, applyPage, p: _p } = widget

  // 普通控件：仅当前页
  if (kind === WidgetKind.NORMAL) return p === _p

  // 未设置：所有页
  if (!applyPage) return true

  // 奇数页
  if (applyPage === ApplyPage.ODD) return !!((p + 1) % 2)

  // 偶数页
  if (applyPage === ApplyPage.EVEN) return !((p + 1) % 2)

  // 指定页
  if (/\d/.test(applyPage)) return isPageInApply(p, resolveBatchPage(applyPage))

  return true
}

/** 获取应用奇偶数页面后实际数量 */
export function getApplyCount(count: number, applyPage?: string) {
  if (applyPage === ApplyPage.ODD) return Math.ceil(count / 2)

  if (applyPage === ApplyPage.EVEN) return Math.floor(count / 2)

  return count
}

/** 获取控件批量应用个数 */
export function getBatchApplyCount(widget: Widget) {
  return [...widget.linkWidgets, widget].reduce((count, w) => {
    return count + w.pages.length
  }, 0)
}
